package com.xyzh05.model;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlRootElement;

import org.compass.annotations.Searchable;
import org.compass.annotations.SearchableId;
import org.compass.annotations.SearchableProperty;
import org.springframework.security.core.GrantedAuthority;

@Entity
@Table(name="role")
@Searchable
@XmlRootElement
public class Role extends BaseObject implements Serializable, GrantedAuthority {
	private static final long serialVersionUID = -861118353778824973L;

	public static final Long ROLE_TYPE_ADMIN = 8L;
	public static final Long ROLE_TYPE_ADVISER = 64L;
	public static final Long ROLE_TYPE_EDITOR_IN_CHIEF = 32L;
	public static final Long ROLE_TYPE_EDITOR = 4L;
	public static final Long ROLE_TYPE_USER = 2L;
	
	public static final String ROLE_ADMIN = "ROLE_ADMIN";
	public static final String ROLE_ADVISER = "ROLE_ADVISER";
	public static final String ROLE_EDITOR_IN_CHIEF = "ROLE_EDITOR_IN_CHIEF";
	public static final String ROLE_EDITOR = "ROLE_EDITOR";
	public static final String ROLE_USER = "ROLE_USER";

	public static final Short DEFAULT_STATUS = 0;
	public static final Short STATUS_RUNING = 1;
	public static final Short STATUS_END = 2;
	
	private Long id;
    private DictItem roleType;
    private User user;
    private String name;
    private String displayName;
    private String description;
    private Short status = DEFAULT_STATUS;
    private Date updateTime = new Date();
    private Set<User> users = new HashSet<User>(0);
    
    /**
     * Default constructor - creates a new instance with no values set.
     */
    public Role() {
    }
    
    /**
     * Create a new instance and set the name.
     *
     * @param name name of the role.
     */
    public Role(final String name) {
        this.name = name;
    }

    @Id @GeneratedValue(strategy=GenerationType.AUTO) @SearchableId    
    public Long getId() {
        return this.id;
    }
    
    public void setId(Long id) {
        this.id = id;
    }
    
	@ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="role_type_id")
    public DictItem getRoleType() {
		return roleType;
	}

	public void setRoleType(DictItem roleType) {
		this.roleType = roleType;
	}
    
	@ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="update_user")
    public User getUser() {
        return this.user;
    }
    
    public void setUser(User user) {
        this.user = user;
    }
    
    @Column(name="name", nullable=false, length=32)
    @SearchableProperty
    public String getName() {
        return this.name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    @Column(name="display_name", length=32)
    @SearchableProperty
    public String getDisplayName() {
        return this.displayName;
    }
    
    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }
    
    @Column(name="description", length=64)
    @SearchableProperty
    public String getDescription() {
        return this.description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    @Column(name="status")
    @SearchableProperty
    public Short getStatus() {
        return this.status;
    }
    
    public void setStatus(Short status) {
        this.status = status;
    }
    
    @Column(name="update_time", nullable=false)
    @SearchableProperty
    public Date getUpdateTime() {
        return this.updateTime;
    }
    
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
    
    @ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    @JoinTable(name="user_role", joinColumns = { 
    @JoinColumn(name="role_id", nullable=false, updatable=false) }, inverseJoinColumns = { 
    @JoinColumn(name="user_id", nullable=false, updatable=false) })
    public Set<User> getUsers() {
        return this.users;
    }
    
    public void setUsers(Set<User> users) {
        this.users = users;
    }


    /**
     * @return the name property (getAuthority required by Acegi's GrantedAuthority interface)
     * @see org.springframework.security.core.GrantedAuthority#getAuthority()
     */
    @Transient
	public String getAuthority() {
		return getName();
	}
    
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Role pojo = (Role) o;

        if (roleType != null ? !roleType.equals(pojo.roleType) : pojo.roleType != null) return false;
        if (user != null ? !user.equals(pojo.user) : pojo.user != null) return false;
        if (name != null ? !name.equals(pojo.name) : pojo.name != null) return false;
        if (displayName != null ? !displayName.equals(pojo.displayName) : pojo.displayName != null) return false;
        if (description != null ? !description.equals(pojo.description) : pojo.description != null) return false;
        if (status != null ? !status.equals(pojo.status) : pojo.status != null) return false;
        if (updateTime != null ? !updateTime.equals(pojo.updateTime) : pojo.updateTime != null) return false;

        return true;
    }

    public int hashCode() {
        int result = 0;
        result = (roleType != null ? roleType.hashCode() : 0);
        result = 31 * result + (user != null ? user.hashCode() : 0);
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
        result = 31 * result + (description != null ? description.hashCode() : 0);
        result = 31 * result + (status != null ? status.hashCode() : 0);
        result = 31 * result + (updateTime != null ? updateTime.hashCode() : 0);

        return result;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer(getClass().getSimpleName());

        sb.append(" [");
        sb.append("id").append("='").append(getId()).append("', ");
        sb.append("roleType").append("='").append(getRoleType()).append("', ");
        sb.append("user").append("='").append(getUser()).append("', ");
        sb.append("name").append("='").append(getName()).append("', ");
        sb.append("displayName").append("='").append(getDisplayName()).append("', ");
        sb.append("description").append("='").append(getDescription()).append("', ");
        sb.append("status").append("='").append(getStatus()).append("', ");
        sb.append("updateTime").append("='").append(getUpdateTime()).append("', ");
        
        sb.append("]");
      
        return sb.toString();
    }

}
